package com.yx.test3d.program;

import android.content.Context;
import android.opengl.GLES20;
import android.opengl.GLES30;

import com.yx.test3d.model.Model;
import com.yx.test3d.utils.LogUtils;

import java.nio.FloatBuffer;

import static android.opengl.GLES20.GL_FRAMEBUFFER;
import static android.opengl.GLES20.GL_TEXTURE0;
import static android.opengl.GLES20.GL_TEXTURE_2D;
import static android.opengl.GLES20.glActiveTexture;
import static android.opengl.GLES20.glBindFramebuffer;
import static android.opengl.GLES20.glBindTexture;
import static android.opengl.GLES20.glBlendFunc;
import static android.opengl.GLES20.glDeleteBuffers;
import static android.opengl.GLES20.glDisable;
import static android.opengl.GLES20.glEnable;
import static android.opengl.GLES20.glGetAttribLocation;
import static android.opengl.GLES20.glGetUniformLocation;
import static android.opengl.GLES20.glUniform1i;
import static android.opengl.GLES20.glUniformMatrix4fv;
import static android.opengl.GLES20.glUseProgram;
import static android.opengl.GLES20.glVertexAttribPointer;
import static android.opengl.GLES20.glViewport;
import static android.opengl.GLES30.glDeleteVertexArrays;

public class ImageProgram extends GLProgram {
    protected int[] vaos;
    protected int[] vbos;
    int texture;
    int textureIndex;
    FloatBuffer vertex;
    private float[] mMatrix = new float[16];
    private float[] vMatrix = new float[16];
    private float[] pMatrix = new float[16];

    public ImageProgram( Context context) {
        String vsc = "#version 300 es\n" +
                "in vec3 position;\n" +
                "in vec2 texCoords;\n" +
                "out vec2 TexCoords;\n" +
                "out vec3 f_position;\n" +
                "uniform mat4 mat_model;\n" +
                "uniform mat4 mat_view;\n" +
                "uniform mat4 mat_proj;\n" +

                "void main()\n" +
                "{\n" +
                "    gl_Position = mat_proj * mat_view  * mat_model * vec4(position,1.0f);\n" +
                "    TexCoords = texCoords;\n" +
                "    f_position = position;\n" +
                "}";

        String fsc = "#version 300 es\n" +
                "in vec2 TexCoords;\n" +
                "in vec3 f_position;\n" +
                "out vec4 color;\n" +
                "\n" +
                "uniform sampler2D screenTexture;\n" +
                "\n" +
                "void main()\n" +
                "{\n" +
                "    float alpha = (0.5-f_position.y);  \n" +
                "    vec4 texture = texture(screenTexture, TexCoords);\n" +
                "    texture = vec4(0.0,0.0,1.0,1.0);\n" +
//                "    color = texture;\n" +
                "    color = vec4(texture.rgb,texture.a*alpha);\n" +
                "}";
        create(vsc, fsc);
    }

    public void setMatrix(float[] mMatrix, float[] vMatrix, float[] pMatrix) {
        this.mMatrix = mMatrix;
        this.vMatrix = vMatrix;
        this.pMatrix = pMatrix;
    }

    public void initData(int textureIndex, int texture, FloatBuffer vertexBuffer, FloatBuffer textureBuffer) {
        LogUtils.i(" index: " + textureIndex + " map: " + texture);
        LogUtils.i(" index: " + vertexBuffer.toString());
        LogUtils.i(" index: " + textureBuffer.toString());
        //        clear();
        this.vertex = vertexBuffer;

        this.textureIndex = textureIndex;
        this.texture = texture;

        vaos = new int[1];
        vbos = new int[2];
        GLES30.glGenVertexArrays(vaos.length, vaos, 0);
        GLES30.glGenBuffers(vbos.length, vbos, 0);

        GLES30.glBindVertexArray(vaos[0]);
        GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, vbos[0]);
        GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER, vertexBuffer.capacity() * 4, vertexBuffer, GLES30.GL_STATIC_DRAW);
        glVertexAttribPointer(glGetAttribLocation(programId, "position"), 3, GLES30.GL_FLOAT, false, 3 * 4, 0);
        GLES30.glEnableVertexAttribArray(glGetAttribLocation(programId, "position"));

        GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, vbos[1]);
        GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER, textureBuffer.capacity() * 4, textureBuffer, GLES30.GL_STATIC_DRAW);
        glVertexAttribPointer(glGetAttribLocation(programId, "texCoords"), 2, GLES30.GL_FLOAT, false, 2 * 4, 0);
        GLES30.glEnableVertexAttribArray(glGetAttribLocation(programId, "texCoords"));

        GLES30.glBindVertexArray(0);

    }


    @Override
    public void initLocation() {

    }

    @Override
    public void genVao(Object model) {

    }

    public void draw(int width, int height) {
        glUseProgram(programId);
        glViewport(0, 0, width, height);
        LogUtils.i("draw image");

        //设置默认的帧缓冲
        glBindFramebuffer(GL_FRAMEBUFFER, GLES20.GL_NONE);
        glDisable(GLES30.GL_CULL_FACE);
        glEnable(GLES30.GL_BLEND);
        glBlendFunc(GLES30.GL_SRC_ALPHA, GLES30.GL_ONE_MINUS_SRC_ALPHA);
        //        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glUniformMatrix4fv(glGetUniformLocation(programId, "mat_model"), 1, false, mMatrix, 0);
        glUniformMatrix4fv(glGetUniformLocation(programId, "mat_view"), 1, false, vMatrix, 0);
        glUniformMatrix4fv(glGetUniformLocation(programId, "mat_proj"), 1, false, pMatrix, 0);

        //激活第 textureIndex 号纹理
        glActiveTexture(GL_TEXTURE0 + textureIndex);
        glBindTexture(GL_TEXTURE_2D, texture);//绑定纹理
        glUniform1i(glGetUniformLocation(programId, "screenTexture"), textureIndex);

        //画
        GLES30.glBindVertexArray(vaos[0]);
        GLES30.glDrawArrays(GLES30.GL_TRIANGLES, 0, vertex.limit() / 3);
        GLES30.glBindVertexArray(0);
        glEnable(GLES30.GL_CULL_FACE);
        glDisable(GLES30.GL_BLEND);
    }

    public void clear() {
        if (vbos != null) {
            glDeleteBuffers(vbos.length, vbos, 0);
        }

        if (vaos != null) {
            glDeleteVertexArrays(vaos.length, vaos, 0);
        }
    }

}
